package com.imooc.bilibili.service.impl;

import com.imooc.bilibili.dao.UserFollowingGroupDao;
import com.imooc.bilibili.dao.UserFollowingInfoDao;
import com.imooc.bilibili.entity.UserFollowingGroup;
import com.imooc.bilibili.entity.UserFollowingInfo;
import com.imooc.bilibili.entity.UserInfo;
import com.imooc.bilibili.enums.DeleteStateEnums;
import com.imooc.bilibili.enums.EnableStateEnums;
import com.imooc.bilibili.enums.GroupTypeEnums;
import com.imooc.bilibili.exception.ConditionException;
import com.imooc.bilibili.request.UserFollowRequest;
import com.imooc.bilibili.service.UserFollowService;
import com.imooc.bilibili.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service("userFollowService")
public class UserFollowServiceImpl implements UserFollowService {

    @Autowired
    private UserFollowingInfoDao userFollowingInfoDao;

    @Autowired
    private UserFollowingGroupDao userFollowingGroupDao;

    @Autowired
    private UserService userService;

    /**
     * 添加事务注解，方便出现错误的时候进行数据回滚
     * @param request
     */
    @Transactional
    @Override
    public void insertUserFollowingsService(UserFollowRequest request) {
        UserFollowingGroup userGroup = new UserFollowingGroup();
        //获取groupId并对groupId进行判断,判断分组信息是否存在
        Long followingGroupId = request.getFollowingGroupId();
        if (null == followingGroupId) {
            //获取默认分组信息
            UserFollowingGroup group = this.getByType(GroupTypeEnums.DEFAULT_GROUP.getCode());
            userGroup.setFollowingGroupId(group.getFollowingGroupId());
        } else {
            //如果分组id被前端传过来，直接根据groupid查询对应分组数据即可
            UserFollowingGroup groupById = this.getGroupById(request.getFollowingGroupId());
            if (null == groupById) {
                throw new ConditionException("分组信息不存在");
            }
        }
        //判断关注的用户信息是否存在
        //获取被关注者的用户id
        Long followingId = request.getFollowId();
        //根据被关注者的用户id查询用户数据，并判断该用户是否存在
        UserInfo userInfo = userService.queryUserByIdService(followingId);
        if (null == userInfo) {
            throw new ConditionException("关注的用户不存在");
        }
        //根据用户id和被关注的用户id删除对应关注信息，在进行信息添加，减少修改成本
        userFollowingInfoDao.deleteUserFollowingService(request.getUserId(), followingId);
        //删除完成之后，开始对关注信息进行添加
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());

        UserFollowingInfo followingInfo = new UserFollowingInfo();
        followingInfo.setUserId(request.getUserId());
        followingInfo.setFollowId(followingId);
        followingInfo.setFollowingGroupId(followingGroupId);
        followingInfo.setEnableState(EnableStateEnums.START_USING.getCode());
        followingInfo.setDeleteState(DeleteStateEnums.UN_DELETED.getCode());
        followingInfo.setCreateTime(timestamp);
        followingInfo.setUpdateTime(timestamp);
        userFollowingInfoDao.insert(followingInfo);
    }

    /**
     * 根据用户id查询该用户的关注列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<UserFollowingGroup> getUserFollowInfosService(Long userId) {
        //根据用户id获取用户的关注信息
        List<UserFollowingInfo> userFollowing = userFollowingInfoDao.getUserFollowingByUserId(userId);
        if (null == userFollowing || userFollowing.isEmpty()) {
            throw new ConditionException("当前用户并未关注任何up主");
        }
        //获取当前用户所有被关注的用户
        List<Long> follwingIds = userFollowing.stream().map(UserFollowingInfo::getFollowId).distinct().collect(Collectors.toList());
        List<UserInfo> userInfos = new ArrayList<>();
        if (follwingIds != null && !follwingIds.isEmpty()) {
            //根据被关注的用户的用户id查询被关注用户的用户信息
            userInfos = userService.getUserInfoByIdsService(follwingIds);
        }
        for (UserFollowingInfo followingInfo : userFollowing) {
            for (UserInfo userInfo : userInfos) {
                if (followingInfo.getFollowId().compareTo(userInfo.getUserId()) == 0) {
                    followingInfo.setUserInfo(userInfo);
                }
            }
        }
        //对关注用户进行分组展示
        //根据用户id查询分组数据
        List<UserFollowingGroup> groupList =userFollowingGroupDao.getGroupByUserId(userId);
        UserFollowingGroup group = new UserFollowingGroup();
        group.setFollowingGroupName(GroupTypeEnums.ALL_GROUP.getMessage());
        group.setFollowingUserInfo(userInfos);
        List<UserFollowingGroup> result = new ArrayList<>();
        result.add(group);
        for (UserFollowingGroup groupInfo : groupList) {
            List<UserInfo> infoList = new ArrayList<>();
            for (UserFollowingInfo followingInfo : userFollowing) {
                if (groupInfo.getFollowingGroupId().equals(followingInfo.getFollowingGroupId())) {
                    infoList.add(followingInfo.getUserInfo());
                }
            }
            group.setFollowingUserInfo(infoList);
            result.add(group);
        }
        return result;
    }

    @Override
    public List<UserFollowingInfo> getUserFansService(Long followingId) {
        //根据followingId获取当前用户的粉丝列表
        List<UserFollowingInfo> fansList = userFollowingInfoDao.queryUserFansByFollowId(followingId);
        if(null == fansList || fansList.isEmpty()) {
            throw new ConditionException("当前用户并未任何人关注");
        }
        //抽出关注了当前用户的用户id
        List<Long> userIds = fansList.stream().map(UserFollowingInfo::getUserId).distinct().collect(Collectors.toList());
        if ( userIds.isEmpty()) {
            throw new ConditionException("当前用户下的粉丝为空");
        }
        //根据用户id查询对应的用户信息
        List<UserInfo> userInfoList = userService.getUserInfoByUserIdsService(userIds);
        if (null == userInfoList || userInfoList.isEmpty()) {
            throw new ConditionException("并未查询到对应的用户信息");
        }
        //根据当前up主的用户id查询当前用户关注的用户
        List<UserFollowingInfo> followingInfoList = userFollowingInfoDao.getUserFollowingByUserId(followingId);
        for (UserFollowingInfo info : fansList) {
            for (UserInfo userInfo : userInfoList) {
                if (info.getUserId().equals(userInfo.getUserId())) {
                    userInfo.setFollowed(false);
                    info.setUserInfo(userInfo);
                }
            }
            for (UserFollowingInfo followingInfo : followingInfoList) {
                if (followingInfo.getFollowId().equals(info.getUserId())) {
                    info.getUserInfo().setFollowed(true);
                }
            }
        }
        return fansList;
    }

    @Override
    public Long insertUserFollowingGroupService(UserFollowRequest request) {
        UserFollowingGroup group = new UserFollowingGroup();

        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        group.setUserId(request.getUserId());
        group.setFollowingGroupName(request.getFollowingGroupName());
        if (null == request.getFollowingGroupType()) {
            group.setFollowingGroupType(GroupTypeEnums.DEFAULT_GROUP.getCode());
        } else {
            group.setFollowingGroupType(request.getFollowingGroupType());
        }
        group.setEnableState(EnableStateEnums.START_USING.getCode());
        group.setDeleteState(DeleteStateEnums.UN_DELETED.getCode());
        group.setCreateTime(timestamp);
        group.setUpdateTime(timestamp);
        userFollowingGroupDao.insert(group);
        Long followingGroupId = group.getFollowingGroupId();
        return followingGroupId;
    }

    @Override
    public List<UserFollowingGroup> getUserFollowingGroupService(Long userId) {
        return userFollowingGroupDao.queryGroupByUserIdService(userId);
    }

    @Override
    public List<UserInfo> checkFollowingStatus(List<UserInfo> pageInfo, Long userId) {
        //根据当前用户id查询关注信息
        List<UserFollowingInfo> userFollowingInfoList = userFollowingInfoDao.getUserFollowingByUserId(userId);
        for (UserInfo info : pageInfo) {
            info.setFollowed(false);
            for (UserFollowingInfo followingInfo :userFollowingInfoList) {
                if (followingInfo.equals(info.getUserId())) {
                    info.setFollowed(true);
                }
            }
        }
        return pageInfo;
    }

    /**
     * 根据类型获取分组信息
     * @return
     */
    public UserFollowingGroup getByType(Integer groupType) {
       return userFollowingGroupDao.queryGroupByType(groupType);
    }

    /**
     * 根据分组id查询对应分组信息
     */
    public UserFollowingGroup getGroupById(Long groupId) {
        return userFollowingGroupDao.queryById(groupId);
    }
}
